package com.greensam.pixelengine.service.kv;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author Macro_Ray
 * @since 2025/7/29 15:02
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class KVStoreImpl implements KVStore {

    private final RedisTemplate<String, String> redisTemplate;

    @Override
    public void set(String key, String value, long timeout) {
        log.debug("set key: {}, value: {}, timeout: {}", key, value, timeout);
        redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
    }

    @Override
    public String get(String key) {
        Object value = redisTemplate.opsForValue().get(key);
        return value != null ? value.toString() : null;
    }

    @Override
    public Boolean delete(String key) {
        return redisTemplate.delete(key);
    }

    @Override
    public Boolean deleteAllByPrefix(String prefix) {
        Set<String> keys = redisTemplate.keys(prefix + "*");

        if (!CollectionUtils.isEmpty(keys)) {
            Long deletedCount = redisTemplate.delete(keys);
            log.debug("Deleted {} keys with prefix: {}", deletedCount, prefix);
            return deletedCount > 0;
        }
        return Boolean.TRUE;
    }

    @Override
    public Boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    @Override
    public Map<String, String> getAllByPrefix(String prefix) {
        Set<String> keys = redisTemplate.keys(prefix + "*");
        Map<String, String> result = new HashMap<>();

        if (!CollectionUtils.isEmpty(keys)) {
            keys.forEach(key -> {
                String value = get(key);
                if (value != null) {
                    result.put(key, value);
                }
            });
        }
        return result;
    }
}
